package com.sdkx.app.util;

import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;

import com.sdkx.app.view.MyCustomDraw;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;

import cn.creable.gridgis.controls.App;
import cn.creable.gridgis.controls.MapControl;
import cn.creable.gridgis.geodatabase.IFeatureClass;
import cn.creable.gridgis.geometry.Arithmetic;
import cn.creable.gridgis.geometry.Envelope;
import cn.creable.gridgis.geometry.IEnvelope;
import cn.creable.gridgis.geometry.Point;
import cn.creable.gridgis.gridMap.IMap;
import cn.creable.gridgis.mapLayer.ILayer;
import cn.creable.gridgis.shapefile.FixedShapefileLayer;
import cn.creable.gridgis.shapefile.ShapefileLayer;
import cn.creable.ucmap.OpenSourceMapLayer;
import cn.creable.ucmap.RasterLayer;


/**
 * 这是一个工具类，实现了gps的管理，一些地图相关函数，以及方位角、距离计算等等
 */
public class Util {

    private static Util instance;
    private MapControl mapControl;
    /**
     * 播放声音
     */
    public void playSound() {
        final MediaPlayer mp = new MediaPlayer();
        mp.reset();
        try {
            mp.setDataSource(App.getInstance(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
            mp.prepare();
            mp.start();

            new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    mp.stop();
                }
            }.start();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void setMapControl(MapControl mapControl) {
        this.mapControl = mapControl;
    }

    public class LocationPoint {
        public long time;
        public double lon, lat;

        public LocationPoint() {

        }

        public LocationPoint(double lon, double lat, long time) {
            this.time = time;
            this.lon = lon;
            this.lat = lat;
        }
    }

    private LocationPoint curLocation;

    private Util() {
        curLocation = null;
    }

    public static Util getInstance() {
        if (instance == null)
            instance = new Util();
        return instance;
    }

    /**
     * 根据图层名获取图层引用
     *
     * @param mapControl
     * @param layerName
     * @return
     */
    public static ILayer getLayerByName(MapControl mapControl, String layerName) {
        IMap map = mapControl.getMap();
        int layerCount = map.getLayerCount();
        ILayer layer;
        for (int i = 0; i < layerCount; ++i) {
            layer = map.getLayer(i);
            if (layer.getName().equalsIgnoreCase(layerName)) {
                return layer;
            }
        }
        return null;
    }

    /**
     * 根据字段名获取字段序号
     *
     * @param fc
     * @param fieldName
     * @return
     */
    public static int getFieldIdByName(IFeatureClass fc, String fieldName) {
        return fc.findField(fieldName);
    }

    /**
     * 将地图以给定的点为中心显示
     *
     * @param mapControl
     * @param x
     * @param y
     */
    public static void centerMapByPoints(MapControl mapControl, double x, double y) {
        IEnvelope env = mapControl.getExtent();
        Point center = new Point(x, y);
        env.centerAt(center);
        mapControl.refresh(env);
        center = null;
    }

    /**
     * 获取全图范围
     *
     * @param map
     * @return
     */
    public static IEnvelope getMapFullExtent(IMap map) {
        int count = map.getLayerCount();
        if (count > 0) {
            IEnvelope env = Envelope.createEnvelope(Double.MAX_VALUE, -Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE);
            for (int i = 0; i < count; ++i) {
                ILayer layer = map.getLayer(i);
                if (layer instanceof OpenSourceMapLayer)
                    return null;
                if (layer instanceof ShapefileLayer) {
                    env.union(((ShapefileLayer) layer).getFullExtent());
                } else if (layer instanceof FixedShapefileLayer) {
                    env.union(((FixedShapefileLayer) layer).getFullExtent());
                } else if (layer instanceof RasterLayer) {
                    env.union(((RasterLayer) layer).getFullExtent());
                }
            }
            return env;
        }
        return null;
    }

    /**
     * 复制文件
     *
     * @param from
     * @param to
     * @return
     */
    public static boolean copy(String from, String to) {
        try {
            String toPath = to.substring(0, to.lastIndexOf(File.separatorChar)); // 提取文件路径
            File f = new File(toPath); // 建立文件目录路
            if (!f.exists())
                f.mkdirs();

            BufferedInputStream bin = new BufferedInputStream(
                    new FileInputStream(from));
            BufferedOutputStream bout = new BufferedOutputStream(
                    new FileOutputStream(to));
            int c;
            while ((c = bin.read()) != -1)
                // 复制
                bout.write(c);
            bin.close();
            bout.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

//    /**
//     * 获取gps历史轨迹
//     *
//     * @param startTime 开始时间  GregorianCalendar.getTimeInMillis返回的值
//     * @param endTime   结束时间  GregorianCalendar.getTimeInMillis返回的值
//     * @return
//     */
//    public ArrayList<LocationPoint> getLocationHistory(long startTime, long endTime) {
//        //构建sql语句
//        String sql = String.format("select lon,lat,time from location_history where time>%d and time<%d", startTime, endTime);
//        Cursor cursor = db.rawQuery(sql, null);
//        if (cursor != null) {//将结果存入数组
//            ArrayList<LocationPoint> lps = new ArrayList<LocationPoint>();
//            while (cursor.moveToNext()) {
//                lps.add(new LocationPoint(cursor.getDouble(0), cursor.getDouble(1), cursor.getLong(2)));
//            }
//            if (lps.isEmpty()) return null;
//            return lps;
//        }
//        return null;
//    }

    /**
     * 计算方位角
     *
     * @param x
     * @param y
     * @param x2
     * @param y2
     * @return
     */
    public double getAngle(double x, double y, double x2, double y2) {
        double dx = y2 - y;
        double dy = x2 - x;
        if (dx == 0) {
            if (dy > 0) return 90;
            else return 270;
        }
        double a = Math.atan(Math.abs(dy / dx)) / Math.PI * 180;
        if (dx > 0 && dy >= 0) {

        } else if (dx < 0 && dy >= 0) {
            a = 180 - a;
        } else if (dx < 0 && dy < 0) {
            a = 180 + a;
        } else if (dx > 0 && dy < 0) {
            a = 360 - a;
        }
        return a;
    }

    public double getDistance(double x, double y, double x2, double y2) {
        byte type = 0;
        if (mapControl.getMap().getMapUnits() == 1)
            type = 1;
        return Arithmetic.Distance(new Point(x, y), new Point(x2, y2), type);
    }
//
//    @Override
//    public void onLocationChanged(Location loc) {
//        if (time != 0 && (loc.getTime() - time) < interval)
//            return;//如果没有达到刷新间隔，则抛弃这个位置信息
//        location = loc;
//        time = loc.getTime();
//        if (curLocation == null) {
//            curLocation = new LocationPoint();
//            playSound();
//        }
//        if (curLocation.time == time) {//数据库中将time做为主键，不允许出现2个相同的时间，所以这里抛弃相同时间的位置信息
//            System.out.println("重复时间获取的位置被抛弃");
//            return;
//        }
//        //修改当前位置curLocation的值，以存储当前位置信息
//        curLocation.lon = loc.getLongitude();
//        curLocation.lat = loc.getLatitude();
//        curLocation.time = time;
//        //向数据库添加位置信息
////        ContentValues cv = new ContentValues();
////        cv.put("lon", curLocation.lon);
////        cv.put("lat", curLocation.lat);
////        cv.put("time", curLocation.time);
////        if (db != null)
////            db.insert("location_history", null, cv);
////        cv = null; ContentValues cv = new ContentValues();
//////        cv.put("lon", curLocation.lon);
//////        cv.put("lat", curLocation.lat);
//////        cv.put("time", curLocation.time);
//////        if (db != null)
//////            db.insert("location_history", null, cv);
//////        cv = null;
//
//        if (mapControl != null) {//将最新的位置信息设置进MyCustomDraw
//            MyCustomDraw mcd = (MyCustomDraw) mapControl.getCustomDraw();
//            mcd.setCurrentLocation(curLocation);
//        }
//    }

    public static String degreePatten(Context context, String degreein) {
        if (context == null || TextUtils.isEmpty(degreein)) return "";
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
        String type = sharedPreferences.getString("zuoBiaoGeShi", "度分秒");
        String degreetemp = degreein;
        if(!degreein.matches("([N]|[S]|[E]|[W]).+")){
            return "";
        }
        degreetemp = degreein.substring(1);
        Double sdegreeinfo = Double.valueOf(degreetemp);
        int sdegree = (int)(sdegreeinfo / 10000);
        int sfen = (int) ((sdegreeinfo % 10000) / 100);
        double sSec = ((sdegreeinfo*100)%10000)/100;
        String result = "";
        if ("度".equals(type)) {
            double fdegree = sdegree + (sfen + sSec / 60) / 60;
            String info = Double.toString(fdegree);
            int pindex = info.indexOf(".");
            if (info.length() - pindex > 6) {
                info = String.format("%.6f", fdegree);
            }
            result = info + "°";
        } else if ("度分".equals(type)) {
            StringBuilder builder = new StringBuilder();
            builder.append(sdegree);
            builder.append("°");
            double ffen = sfen + sSec / 60;
            String info = Double.toString(ffen);
            int index = info.indexOf(".");
            if (info.length() - index > 6) {
                info = String.format("%.6f", ffen);
            }
            builder.append(info);
            builder.append("′");
            result = builder.toString();
        } else if ("度分秒".equals(type)) {
            StringBuilder builder = new StringBuilder();
            builder.append(sdegree);
            builder.append("°");
            builder.append(sfen);
            builder.append("′");
            if (sSec > 0) {
                if (sSec - ((int) sSec) > 0)
                    builder.append(sSec);
                else {
                    builder.append((int) sSec);
                }
            } else {
                builder.append("00");
            }
            builder.append("″");
            result = builder.toString();
        }
        return degreein.charAt(0)+result;
    }

    public static String toStardardDegree(String info){
            double res = 1;
            int degree = info.indexOf('°', 1);
            int part1 = info.indexOf('′', degree);
            int part2 = info.indexOf('″', part1);
            String sdegree = "";
            String sfen = "";
            String miao = "";
            if (degree >= 0)
                sdegree = info.substring(1, degree);

            if (part1 >= 0) {
                if (degree < 0)
                    degree = 0;
                sfen = info.substring(degree + 1, part1);
            }

            if (part2 > 0) {
                int precount = part1;
                if (precount < 0)
                    precount = degree;
                if (precount < 0)
                    precount = 0;
                miao = info.substring(precount + 1, part2);
            }
            StringBuilder builder = new StringBuilder();
            builder.append(info.charAt(0));
            if (sdegree.contains(".")) {
                double alldata = Double.valueOf(sdegree);
                builder.append((int) alldata);
                double afendata = (alldata - ((int) alldata)) * 60;
                if(((int) afendata) < 10)
                    builder.append("0");
                builder.append((int) afendata);
                double isec = (afendata - ((int) afendata)) * 60;
                if(((int)isec)<10)
                    builder.append("0");
                builder.append(String.format("%.2f",isec));
                return builder.toString();
            } else {
                if (!TextUtils.isEmpty(sdegree)) {
                    builder.append(sdegree);
                } else {
                    builder.append("00");
                }
            }
            if (sfen.contains(".")) {
                double fendata = Double.valueOf(sfen);
                if(((int)fendata) < 10 )
                    builder.append("0");
                builder.append((int) fendata);
                double sec = (fendata - ((int) fendata)) * 60;
                if(((int)sec)<10)
                    builder.append("0");
                builder.append(String.format("%.2f",sec));
                return builder.toString();
            } else {
                if (!TextUtils.isEmpty(sfen)) {
                    if(sfen.length()<2)
                        builder.append("0");
                    builder.append(sfen);
                } else {
                    builder.append("00");
                }
            }
            if (!TextUtils.isEmpty(miao)) {
                double dmiao = Double.valueOf(miao);
                if(((int)dmiao) < 10)
                    builder.append("0");
                builder.append(String.format("%.2f",dmiao));
            } else {
                builder.append("00.00");
            }
            return builder.toString();

    }

}

